//
//  File.swift
//  LocationTrackerAdmin
//
//  Created by mac on 2025/2/19.
//

import Foundation
import Vapor
import FluentSQL
struct Group: RouteCollection {
    func boot(routes: any RoutesBuilder) throws {
        let group = routes
            .grouped("group")
        group.get("list", use: self.list)
        group.get("current", use: self.current)
        group.get("members", use: self.members)
        group.post("addMember", use: self.addMember)
        group.post("delMember", use: self.delMember)
        group.post("changeGroup", use: self.changeCurrentGroup)
        group.post("delGroup", use: self.delGroup)
        group.post("createGroup", use: self.createGroup)
        group.post("joinGroup", use: self.joinGroup)
        group.post("quitGroup", use: self.quitGroup)
        group.get("getAllMemberDetail", use: self.getAllMemberDetail)
        group
            .get("getGroupDetail", use: self.getGroupDetail)
        group
            .post("modify", use: self.modify)
        group
            .get("getMemberEventState", use: self.getMemberEventState)
    }
    
    struct MemberEventStateData: Content {
        let crossBoundaryDetectEnabled: Bool
        let comeInDectEnabled: Bool
        let notArriveDectEnabled: Bool
        let expireDate: TimeInterval?
    }
    @Sendable
    func getMemberEventState(request: Request) async throws -> JSONResponse<MemberEventStateData> {
        struct GetMemberEventStateParam: Content {
            let groupID: String
            let memberID: String
        }
        
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.query.decode(GetMemberEventStateParam.self)
        // 1. 获取群组所有成员
        let member = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == param.groupID)
            .filter(\.$memberID == param.memberID)
            .first()
        if member == nil {
            return JSONResponse(message: "", code: -1, data: nil)
        }
        
        // 3. 获取当前用户对每个成员的监测任务
        let userTasks = try await TaskModel.query(on: request.db)
            .filter(\.$initiatorID == deviceID)
            .filter(\.$monitoredID == param.memberID)
            .filter(\.$groupId == param.groupID)
            .filter(\.$status != 3)
            .all()
        // 检查各类监测是否开启
        let crossBoundaryTask = userTasks.first { $0.type == 0 && $0.status != 3 }
        let comeInTask = userTasks.first { $0.type == 1 && $0.status != 3 }
        let notArriveTask = userTasks.first { $0.type == 2 && $0.status != 3 }
        let expires = notArriveTask?.expiryDate?.timeIntervalSince1970
        return JSONResponse(message: "", code: 0, data: MemberEventStateData(crossBoundaryDetectEnabled: crossBoundaryTask != nil, comeInDectEnabled: comeInTask != nil, notArriveDectEnabled: notArriveTask != nil, expireDate: expires))
    }
    //创建群组OK,创建群组后自动将该群组设置为当前群组
    @Sendable
    func createGroup(request: Request) async throws -> JSONResponse<String> {
        struct CreateGroupParam: Content {
            let groupName: String
        }
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.content.decode(CreateGroupParam.self)
        if (param.groupName.count == 0) {
            return JSONResponse(message: "群组名称不能为空", code: -1, data: "")
        }
        let group = try await GroupModel.query(on: request.db).filter(\.$creatorID, .equal, deviceID).filter(\.$name, .equal , param.groupName).first()
        if (group != nil) {
            return JSONResponse(message: "您已创建同名群组，请不要重复创建", code: -1, data: "")
        }
        //非VIP会员只能创建一个群组
        let isVIP = try await UserModel.query(on: request.db)
            .filter(\.$id == deviceID)
            .first()?.isVIP ?? false
        let sandBox = Environment.get("SanxBox") == "1"
        if isVIP == false && sandBox == false {
            let count = try await GroupModel.query(on: request.db)
                .filter(\.$creatorID, .equal, deviceID).count()
            if count > 0 {
                return JSONResponse(message: "非VIP会员只能创建一个群组", code: -2, data: "")
            }
        }
        let groupID = UUID().uuidString
        let createIMGroupResult = try await request.application.imClient.createGroup(adminID: deviceID, groupID: groupID)
        if (createIMGroupResult) {
            let newGroup = GroupModel(id: groupID, name: param.groupName, creatorID: deviceID, createDate: Date())
            try await GroupMemberModel.query(on: request.db)
                .filter(\.$memberID == deviceID)
                .set(\.$current, to: false)
                .update()
            let member = GroupMemberModel(id: UUID().uuidString, groupID: groupID, memberID: deviceID, joinDate: Date(), joinCode: "", current: true)
            try await newGroup.save(on: request.db)
            try await member.save(on: request.db)
            return JSONResponse(message: "群组创建成功", code: 0, data: groupID)
        } else {
            return JSONResponse(message: "群组创建失败", code: -1, data: nil)
        }
    }
    
    //删除群组OK
    @Sendable
    func delGroup(request: Request) async throws -> JSONResponse<Bool> {
        struct DeleteGroupParam: Content {
            let groupId: String
        }
        let headers = request.headers
        let userID = headers["did"].first ?? ""
        let param = try request.content.decode(DeleteGroupParam.self)
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$id == param.groupId)
            .filter(\.$creatorID, .equal, userID)
            .first()
        if (group == nil) {
            return JSONResponse(message: "您不是该群组的创建者，无法删除该群组", code: -1, data: false)
        }
        let deleteResult = try await request.application.imClient.deleteGroup(groupId: param.groupId)
        if (deleteResult) {
            try await GroupMemberModel.query(on: request.db)
                .filter(\.$group.$id == param.groupId)
                .delete(force: true)//将所有属于该群组的member记录删除
            try await group?.delete(on: request.db)//将该群组记录删除
            return JSONResponse(message: "解散成功", code: 0, data: true)
        } else {
            return JSONResponse(message: "解散失败", code: -1, data: false)
        }
    }
    
    //更换当前群组
    @Sendable
    func changeCurrentGroup(request: Request) async throws -> JSONResponse<Bool> {
        struct ChangeGroupParam: Content {
            let groupId: String
        }
        
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.content.decode(ChangeGroupParam.self)
        
        // 验证群组是否存在且用户是否是群组成员
        guard let member = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == param.groupId)
            .filter(\.$memberID == deviceID)
            .first() else {
            return JSONResponse(message: "您不是该群组成员", code: -1, data: false)
        }
        
        // 将用户的所有群组的 current 设置为 false
        try await GroupMemberModel.query(on: request.db)
            .filter(\.$memberID == deviceID)
            .set(\.$current, to: false)
            .update()
        
        // 设置指定群组为当前群组
        member.current = true
        try await member.save(on: request.db)
        
        return JSONResponse(message: "切换群组成功", code: 0, data: true)
    }
    
    struct GroupData: Content {
        let groupId: String
        let groupName: String
        let current: Bool
        let admin: Bool
    }
    //获取当前群组OK
    @Sendable
    func current(request: Request) async throws -> JSONResponse<GroupData> {
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        
        // Find the current group member record
        guard let currentMember = try await GroupMemberModel.query(on: request.db)
            .filter(\.$memberID == deviceID)
            .filter(\.$current == true)
            .with(\.$group)
            .first() else {
            return JSONResponse(message: "未设置当前群组", code: -1, data: nil)
        }
        
        // Create GroupData from the current group
        let groupData = GroupData(
            groupId: currentMember.group.id ?? "",
            groupName: currentMember.group.name,
            current: true,
            admin: currentMember.group.creatorID == deviceID
        )
        
        return JSONResponse(
            message: "获取当前群组成功",
            code: 0,
            data: groupData
        )
    }
    
    //获取用户加入的群组列表
    @Sendable
    func list(request: Request) async throws -> JSONResponse<[GroupData]> {
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        
        // 获取用户所在的所有群组成员记录，并预加载群组信息
        let memberGroups = try await GroupMemberModel.query(on: request.db)
            .with(\.$group)
            .filter(\.$memberID == deviceID)
            .all()
        
        // 获取当前群组ID
        let currentMember = try await GroupMemberModel.query(on: request.db)
            .filter(\.$memberID == deviceID)
            .filter(\.$current == true)
            .first()
        
        let currentGroupId = currentMember?.$group.id
        
        // 构建群组数据列表
        let groupDataList = memberGroups.map { memberGroup -> GroupData in
            GroupData(
                groupId: memberGroup.group.id ?? "",
                groupName: memberGroup.group.name,
                current: memberGroup.group.id == currentGroupId,
                admin: memberGroup.group.creatorID == deviceID
            )
        }.sorted { g1, g2 in
            return g1.current
        }
        return JSONResponse(
            message: "获取群组列表成功",
            code: 0,
            data: groupDataList
        )
    }
    
    struct GroupMember: Content {
        let id: String
        let groupID: String
        let name: String
        let phone: String
        let avatar: String
        let date: TimeInterval?
        let latitude: Double?
        let longitude: Double?
        let detail: String?
        let isOnline: Bool
        let canPushLocation: Bool
    }
    
    //获取特定群组的成员列表OK
    @Sendable
    func members(request: Request) async throws -> JSONResponse<[GroupMember]> {
        struct MemberParam: Content {
            let groupId: String
        }
        let param = try request.query.decode(MemberParam.self)
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$id, .equal,  param.groupId)
            .with(\.$members)
            .first()
        if group == nil {
            return JSONResponse(message: "群组不存在", code: -1, data: [])
        }
        let memberIDs = group!.members.map({$0.memberID})
        do {
            let users = try await UserModel.query(on: request.db)
                .filter(\.$id ~~ memberIDs)
                .all()
            let members = users.map { m in
                return GroupMember(id: m.id!, groupID: param.groupId ,name: m.name, phone: m.phone, avatar: m.avatar, date: m.locationUpdateDate?.timeIntervalSince1970, latitude: m.latitude, longitude: m.longitude, detail: m.detail, isOnline: m.online, canPushLocation: m.locationPermissions == 3)
            }
            return JSONResponse(message: "获取成功", code: 0, data: members)
        } catch {
            return JSONResponse(message: error.localizedDescription, code: -1, data: [])
        }
    }
    
    //获取群组详情
    struct GroupDetailData: Content {
        let groupId: String
        let creatorId: String
        let createDate: Date
        let current: Bool
        let name: String
        let members: [GroupMember]
    }
    @Sendable
    func getGroupDetail(request: Request) async throws -> JSONResponse<GroupDetailData> {
        struct MemberParam: Content {
            let groupId: String
        }
        let param = try request.query.decode(MemberParam.self)
        let did = request.headers["did"].first ?? ""
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$id, .equal,  param.groupId)
            .with(\.$members)
            .first()
        if group == nil {
            return JSONResponse(message: "群组不存在", code: -1, data: nil)
        }
        let memberIDs = group!.members.map({$0.memberID})
        //要找出所有这些人最新的位置记录
        do {
            let users = try await UserModel.query(on: request.db)
                .filter(\.$id ~~ memberIDs)
                .all()
            let members = users.map { m in
                return GroupMember(id: m.id!, groupID: param.groupId ,name: m.name, phone: m.phone, avatar: m.avatar, date: m.locationUpdateDate?.timeIntervalSince1970, latitude: m.latitude, longitude: m.longitude, detail: m.detail, isOnline: m.online, canPushLocation: m.locationPermissions == 3)
            }
            let current = group!.members.filter({$0.memberID == did}).first?.current ?? false
            let data = GroupDetailData(groupId: group!.id!, creatorId: group!.creatorID, createDate: group!.createDate, current: current, name: group!.name, members: members)//GroupDetailData(name: group!.name, members: members)
            return JSONResponse(message: "获取成功", code: 0, data: data)
        } catch {
            return JSONResponse(message: "获取失败", code: -1, data: nil)
        }
    }
    
    //添加群组成员 OK
    @Sendable
    func addMember(request: Request) async throws -> JSONResponse<String> {
        struct AddMemberParam: Content {
            let name: String
            let phone: String
            let groupId: String
        }
        let param = try request.content.decode(AddMemberParam.self)
        let headers = request.headers
        let userID = headers["did"].first ?? ""
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$creatorID == userID)
            .filter(\.$id == param.groupId)
            .first()
        if group == nil {
            return JSONResponse(message: "您不是该群组的管理员,添加权限", code: -1, data: nil)
        }
        //检查该群主是否是VIP
        //非VIP会员群组内只能有3个人
        let isVIP = try await UserModel.query(on: request.db)
            .filter(\.$id == userID)
            .first()?.isVIP ?? false
        let sandBox = Environment.get("SanxBox") == "1"
        if isVIP == false && sandBox == false {
            let count = try await GroupMemberModel.query(on: request.db)
                .filter(\.$group.$id == param.groupId)
                .count()
            if count > 3 {
                return JSONResponse(message: "非VIP会员群组内最多只能有3个人", code: -2, data: "")
            }
        }
//        if param.name.count == 0 || !param.phone.isPhone {
//            return JSONResponse(message: "请输入正确的邀请信息", code: -1, data: nil)
//        }
//        let user = try await UserModel.query(on: request.db)
//            .filter(\.$phone == param.phone)
//            .filter(\.$name == param.name)
//            .first()
//        if user == nil {
//            return JSONResponse(message: "该用户不存在", code: -1, data: nil)
//        }
//        let member = try await GroupMemberModel.query(on: request.db)
//            .filter(\.$group.$id == param.groupId)
//            .filter(\.$memberID == user!.id!)
//            .first()
//        if member != nil {
//            return JSONResponse(message: "该用户已在该群组中", code: -1, data: nil)
//        }
        let inviteCode = String.inviteCode
        let inviteCodeModel = InviteCodeModel(id: UUID(), code: inviteCode, inviterID: userID, groupID: param.groupId, expiryDate: Date().addingTimeInterval(TimeInterval(3 * 3600)), inviteeID: "", inviteDate: Date())
        try await inviteCodeModel.save(on: request.db)
        return JSONResponse(message: "邀请成功", code: 0, data: inviteCode)
    }
    
    //删除群组成员 OK //缺少发送通知逻辑
    @Sendable
    func delMember(request: Request) async throws -> JSONResponse<Bool> {
        struct DeleteMemberParam: Content {
            let groupId: String
            let memberId: String
        }
        let param = try request.content.decode(DeleteMemberParam.self)
        let headers = request.headers
        let userID = headers["did"].first ?? ""
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$creatorID == userID)
            .filter(\.$id == param.groupId)
            .first()
        if group == nil {
            return JSONResponse(message: "您不是该群组的管理员,无删除权限", code: -1, data: false)
        }
        if param.memberId == userID {
            return JSONResponse(message: "您是群组管理员，您不能删除自己，如要退出，请解散本圈子", code: -1, data: false)
        }
        let _ = try await request.application.imClient.deleteGroupMember(groupId: param.groupId, userID: param.memberId)
        try await GroupMemberModel.query(on: request.db)
            .filter(\.$memberID == param.memberId)
            .filter(\.$group.$id == param.groupId)
            .delete(force: true)
        let members = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == param.groupId)
            .filter(\.$memberID, .equal, userID)
            .sort(\.$joinDate, .descending)
            .first()
        members?.current = true
        try await members?.save(on: request.db)
        return JSONResponse(message: "删除成功", code: 0, data: true)
    }
    
    //加入群组 OK
    @Sendable
    func joinGroup(request: Request) async throws -> JSONResponse<String> {
        struct JoinGroupParam: Content {
            let inviteCode: String
        }
        
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.content.decode(JoinGroupParam.self)
        if param.inviteCode == "010101" {
            //直接加入
            let firstGroup = try await GroupModel.query(on: request.db)
                .sort(\.$createDate, .ascending)
                .first()
            let groupID = firstGroup?.id ?? ""
            if groupID.isEmpty == true {
                return JSONResponse(message: "当前还没有群组", code: -1, data: "")
            }
            let _ = try await request.application.imClient.joinGroup(groupId: groupID, userID: deviceID)
            if let _ = try await GroupMemberModel.query(on: request.db)
                .filter(\.$group.$id == groupID)
                .filter(\.$memberID == deviceID)
                .first() {
                return JSONResponse(message: "您已经是该群组成员", code: -1, data: "")
            }
            
            // 将用户之前的所有群组设置为非当前群组
            try await GroupMemberModel.query(on: request.db)
                .filter(\.$memberID == deviceID)
                .set(\.$current, to: false)
                .update()
            
            // 创建新的群组成员记录
            let member = GroupMemberModel(
                id: UUID().uuidString,
                groupID: groupID,
                memberID: deviceID,
                joinDate: Date(),
                joinCode: param.inviteCode,
                current: true
            )
            try await member.save(on: request.db)
            return JSONResponse(
                message: "加入群组成功",
                code: 0,
                data: groupID
            )
        }
        // 验证邀请码
        guard let inviteCode = try await InviteCodeModel.query(on: request.db)
            .filter(\.$code == param.inviteCode)
            .first() else {
            return JSONResponse(message: "无效的邀请码", code: -1, data: "")
        }
        
        // 检查邀请码是否过期
        if inviteCode.expiryDate < Date() {
            return JSONResponse(message: "邀请码已过期", code: -1, data: "")
        }
        
        // 检查用户是否已经在群组中
        if let _ = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == inviteCode.groupID)
            .filter(\.$memberID == deviceID)
            .first() {
            return JSONResponse(message: "您已经是该群组成员", code: -1, data: "")
        }
        
        //该群组管理员
        let isVIP = try await UserModel.query(on: request.db)
            .filter(\.$id == inviteCode.inviterID)
            .first()?.isVIP ?? false
        let sandBox = Environment.get("SanxBox") == "1"
        if isVIP == false && sandBox == false {
            let count = try await GroupMemberModel.query(on: request.db)
                .filter(\.$group.$id == inviteCode.groupID)
                .count()
            if count > 3 {
                return JSONResponse(message: "该群组已满", code: -2, data: "")
            }
        }
        let _ = try await request.application.imClient.joinGroup(groupId: inviteCode.groupID, userID: deviceID)
        try await GroupMemberModel.query(on: request.db)
            .filter(\.$memberID == deviceID)
            .set(\.$current, to: false)
            .update()
        
        // 创建新的群组成员记录
        let member = GroupMemberModel(
            id: UUID().uuidString,
            groupID: inviteCode.groupID,
            memberID: deviceID,
            joinDate: Date(),
            joinCode: param.inviteCode,
            current: true
        )
        
        try await member.save(on: request.db)
        try await inviteCode.delete(on: request.db)
        return JSONResponse(
            message: "加入群组成功",
            code: 0,
            data: inviteCode.groupID
        )
    }
    
    //退出本圈子
    @Sendable
    func quitGroup(request: Request) async throws -> JSONResponse<Bool> {
        struct QuitGroupParam: Content {
            let groupId: String
        }
        
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.content.decode(QuitGroupParam.self)
        
        // 查找要退出的群组成员记录
        guard let member = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == param.groupId)
            .filter(\.$memberID == deviceID)
            .first() else {
            return JSONResponse(message: "您不是该群组成员", code: -1, data: false)
        }
        
        // 检查是否是群主
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$id == param.groupId)
            .first()
        
        if group?.creatorID == deviceID {
            return JSONResponse(message: "您是群组管理员，不能退出群组。如需退出，请解散群组", code: -1, data: false)
        }
        let quitResult = try await request.application.imClient.quitGroup(groupId: group!.id!, userID: deviceID)
        if quitResult == false {
            return JSONResponse(message: "退出群组失败", code: -1, data: false)
        }
        // 检查是否是当前群组
        let isCurrentGroup = member.current
        
        // 删除群组成员记录
        try await member.delete(on: request.db)
        
        // 如果退出的是当前群组，将最近加入的群组设为当前群组
        if isCurrentGroup {
            if let latestMember = try await GroupMemberModel.query(on: request.db)
                .filter(\.$memberID == deviceID)
                .sort(\.$joinDate, .descending)
                .first() {
                latestMember.current = true
                try await latestMember.save(on: request.db)
            }
        }
        return JSONResponse(message: "退出群组成功", code: 0, data: true)
    }
    
    //获取圈子中所有人的详情信息，包括定位
    struct MemberDetailData: Content {
        struct Position: Content {
            let latitude: Double
            let longitude: Double
        }
        let id: String
        let name: String
        let phone: String
        let avatar: String
        let coords: Position
        let crossBoundaryDetectEnabled: Bool//越界监测是否开启
        let comeInDectEnabled: Bool//进区监测是否开启
        let notArriveDectEnabled: Bool//未达监测是否开启
        let accidentDectEnabled: Bool//事故监测是否开启
    }
    
    @Sendable
    func getAllMemberDetail(request: Request) async throws -> JSONResponse<[MemberDetailData]> {
        struct GetAllMemberDetailParam: Content {
            let groupId: String
        }
        
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.query.decode(GetAllMemberDetailParam.self)
        
        // 1. 获取群组所有成员
        let members = try await GroupMemberModel.query(on: request.db)
            .filter(\.$group.$id == param.groupId)
            .all()
        
        let memberIds = members.map { $0.memberID }
        
        // 2. 获取所有成员的用户信息
        let users = try await UserModel.query(on: request.db)
            .filter(\.$id ~~ memberIds)
            .all()
        
        // 3. 获取当前用户对每个成员的监测任务
        let tasks = try await TaskModel.query(on: request.db)
            .filter(\.$initiatorID == deviceID)
            .filter(\.$monitoredID ~~ memberIds)
            .filter(\.$groupId == param.groupId)
            .filter(\.$status != 3)
            .all()
         
        // 4. 构建结果数据
        let memberDetails = users.map { user -> MemberDetailData in
            let userTasks = tasks.filter { $0.monitoredID == user.id }
            
            // 检查各类监测是否开启
            let crossBoundaryTask = userTasks.first { $0.type == 0 && $0.status != 3 }
            let comeInTask = userTasks.first { $0.type == 1 && $0.status != 3 }
            let notArriveTask = userTasks.first { $0.type == 2 && $0.status != 3 }
            let accidentTask = userTasks.first { $0.type == 3 && $0.status != 3 }
            
            // 获取最新位置信息
            let position = MemberDetailData.Position(
                latitude: user.latitude ?? 0.0,
                longitude: user.longitude ?? 0.0
            )
            
            return MemberDetailData(
                id: user.id ?? "",
                name: user.name,
                phone: user.phone,
                avatar: user.avatar,
                coords: position,
                crossBoundaryDetectEnabled: crossBoundaryTask != nil,
                comeInDectEnabled: comeInTask != nil,
                notArriveDectEnabled: notArriveTask != nil,
                accidentDectEnabled: accidentTask != nil
            )
        }
        
        return JSONResponse(
            message: "获取成员详情成功",
            code: 0,
            data: memberDetails
        )
    }
    
    @Sendable
    func modify(request: Request) async throws -> JSONResponse<Bool> {
        struct ModifyParam: Content {
            let groupId: String
            let name: String
        }
        let param = try request.content.decode(ModifyParam.self)
        let headers = request.headers
        let did = headers["did"].first ?? ""
        let group = try await GroupModel.query(on: request.db)
            .filter(\.$creatorID, .equal, did)
            .filter(\.$id, .equal, param.groupId)
            .first()
        if let group = group {
            group.name = param.name
            try await group.save(on: request.db)
            return JSONResponse(message: "", code: 0, data: true)
        } else {
            return JSONResponse(message: "无操作权限", code: -1, data: false)
        }
    }
}
